import fs from 'fs';
import path from 'path';

const DEFAULT_STATE = {
    version: 1,
    steps: {}
};

export class NbGoStateManager {
    /**
     * @param {string} stateFilePath 状态文件路径
     * @param {import('../../utils/Logger.js').Logger} logger 日志
     */
    constructor(stateFilePath, logger) {
        this.stateFilePath = stateFilePath;
        this.logger = logger;
        this.state = null;
    }

    /**
     * 初始化状态文件
     * @returns {Promise<void>}
     */
    async init() {
        if (this.state) {
            return;
        }
        this.state = await this.loadStateFromFile();
    }

    /**
     * 从文件读取状态
     * @returns {Promise<object>}
     */
    async loadStateFromFile() {
        try {
            if (!fs.existsSync(this.stateFilePath)) {
                return {...DEFAULT_STATE};
            }
            const raw = await fs.promises.readFile(this.stateFilePath, 'utf-8');
            if (!raw.trim()) {
                return {...DEFAULT_STATE};
            }
            const parsed = JSON.parse(raw);
            if (typeof parsed !== 'object' || parsed === null) {
                return {...DEFAULT_STATE};
            }
            if (!parsed.steps || typeof parsed.steps !== 'object') {
                parsed.steps = {};
            }
            return parsed;
        } catch (error) {
            this.logger.warn(`读取 nb go 状态文件失败，将重新初始化: ${error.message}`);
            return {...DEFAULT_STATE};
        }
    }

    /**
     * 写入状态文件
     * @returns {Promise<void>}
     */
    async persist() {
        const dir = path.dirname(this.stateFilePath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, {recursive: true});
        }
        const data = JSON.stringify(this.state, null, 2);
        await fs.promises.writeFile(this.stateFilePath, data, 'utf-8');
    }

    /**
     * 获取指定步骤的状态
     * @param {string} stepKey
     * @returns {{status:string,metadata?:object,updatedAt?:string}|null}
     */
    getStep(stepKey) {
        if (!this.state) {
            throw new Error('NbGoStateManager 尚未初始化');
        }
        return this.state.steps?.[stepKey] ?? null;
    }

    /**
     * 更新指定步骤状态
     * @param {string} stepKey
     * @param {'pending'|'skipped'|'completed'|'failed'} status
     * @param {object} [metadata]
     * @returns {Promise<void>}
     */
    async updateStep(stepKey, status, metadata = {}) {
        if (!this.state) {
            throw new Error('NbGoStateManager 尚未初始化');
        }
        const existing = this.state.steps?.[stepKey] ?? {};
        const nextMetadata = metadata ? {...metadata} : {};
        this.state.steps[stepKey] = {
            ...existing,
            status,
            metadata: nextMetadata,
            updatedAt: new Date().toISOString()
        };
        await this.persist();
    }

    /**
     * 获取指定步骤的元数据
     * @param {string} stepKey
     * @returns {object|null}
     */
    getMetadata(stepKey) {
        const step = this.getStep(stepKey);
        return step?.metadata ?? null;
    }
}
